/****************************************************
          File Name:12-2_imply.cpp
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Thu 25 Dec 2014 03:11:10 PM CST
*****************************************************/

#include"12-2.h"
#include<cctype>
#include<cstring>

using std::cin;
using std::cout;

String::String(const char *s)
{
    str = new char[strlen(s) + 1];
    strcpy(str, s);
}

String::String()
{
    str = new char[1];
    str[0] = '\0';
}

String::String(const String & st)
{
    str = new char[strlen(st.str) + 1];
    strcpy(str, st.str);
}

String::~String()
{
    delete [] str;
}

// overload operators

String & String::operator=(const String & st)
{
    if(this == &st)
        return *this;
    delete [] str;
    str = new char[strlen(st.str) + 1];
    strcpy(str, st.str);
    return *this;
}

String & String::operator=(const char *s)
{
    delete [] str;
    str = new char[strlen(s) + 1];
    strcpy(str, s);
    return *this;
}

char & String::operator[](int i)
{
    return str[i];
}

const char & String::operator[](int i) const
{
    return str[i];
}

// overload operator+
// b = a + "this" -> b = a.operator+("this"); a shal not change!!
String  String::operator+(const char *s)
{
	String res;
	
	res.str = new char[strlen(str) + strlen(s) + 1];
	strcpy(res.str, str);
	strcat(res.str, s);
	
	return res; 
}
// b = a + c; --> b = a.operator+(c); a and c shall not change !!
String  String::operator+(const String & s)
{
	String res;
	
	res.str = new char[strlen(s.str) + strlen(str) + 1];
	strcpy(res.str, str);
	strcat(res.str, s.str);
	
	return res;
}

String  operator+(const char *s, String & st)
{
    size_t len;
    String tmp;

    len = strlen(s) + strlen(st.str);

    tmp.str = new char[len + 1];
    strcpy(tmp.str, s);
    strcat(tmp.str, st.str);

    return tmp;
}

bool operator<(const String &st1, const String &st2)
{
    return (strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String &st1, const String &st2)
{
    return st2 < st1;
}

bool operator==(const String &st1, const String &st2)
{
    return (strcmp(st1.str, st2.str) == 0);
}

ostream & operator<<(ostream & os, const String & st)
{
    os << st.str;
    return os;
}

istream & operator>>(istream & is, String & st)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if(is)
        st = temp;
    while(is && is.get() != '\n')
        continue;

    return is;
}

// showlower & showupper

void String::stringlow()
{
    size_t len = strlen(str);
    for(int i = 0; i < len; i++)
        cout << char(tolower(str[i]));
	std::cout << "\n";
}

void String::stringup()
{
    size_t len = strlen(str);
    for(int i=0; i<len; i++)
        std::cout << char(toupper(str[i]));
	std::cout << "\n";
}

int String::has(char ch)
{
    int res = 0;
    for(int i=0; str[i]!='\0'; i++)
    {
        if(str[i] == ch)
            res++;
    }
    return res;
}
